﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;

namespace HYView
{
	public class CreatePartial3dView
	{
		public CreatePartial3dView(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
			this.m_Doc = this.m_Revit.Application.ActiveUIDocument.Document;
		}

		public void Create(ref View3D view3d)
		{
			if (!(this.m_Revit.Application.ActiveUIDocument.ActiveView is ViewPlan))
			{
				return;
			}
			Partial3DViewForm partial3DViewForm = new Partial3DViewForm(this.m_Revit);
			if (partial3DViewForm.ShowDialog() != DialogResult.OK)
			{
				return;
			}
			double num = partial3DViewForm.BottomElevation();
			double num2 = partial3DViewForm.TopElevation();
			if (this.Lessthan_Or_Equal(num2, num))
			{
				num2 = num + AssistFunc.mmToFeet(4000.0);
			}
			PickedBox pickedBox = null;
			try
			{
				pickedBox = this.m_Revit.Application.ActiveUIDocument.Selection.PickBox((Autodesk.Revit.UI.Selection.PickBoxStyle)0, "选择一个矩形区域");
			}
			catch (Exception)
			{
				return;
			}
			if (pickedBox == null)
			{
				return;
			}
			double x = pickedBox.Min.X;
			double x2 = pickedBox.Max.X;
			if (x > x2)
			{
				x = pickedBox.Max.X;
				x2 = pickedBox.Min.X;
			}
			double y = pickedBox.Min.Y;
			double y2 = pickedBox.Max.Y;
			if (y > y2)
			{
				y = pickedBox.Max.Y;
				y2 = pickedBox.Min.Y;
			}
			BoundingBoxXYZ boundingBoxXYZ = new BoundingBoxXYZ();
			boundingBoxXYZ.Min = new XYZ(x, y, num);
			boundingBoxXYZ.Max = new XYZ(x2, y2, num2);
			XYZ direction = new XYZ(-1.0, 1.0, -1.0);
			view3d = RevitVersionFuncs.NewView3D(this.m_Doc, direction);
			if (view3d == null)
			{
				YJKMessageBox.Show("缺少View3DFamilyType");
				return;
			}
			view3d.SetYJKSectionBox(boundingBoxXYZ);
			if (view3d.CanModifyDetailLevel())
			{
				view3d.DetailLevel = partial3DViewForm.DetailLevel;
			}
			view3d.DisplayStyle = partial3DViewForm.ViewDisplayStyle;
			this.get3dViewName(this.m_Doc, view3d, partial3DViewForm.Temp3dViewNameSetting);
			if (!partial3DViewForm.ShowSectionBox)
			{
				IEnumerable<Element> enumerable = new FilteredElementCollector(this.m_Doc).OfCategory(BuiltInCategory.OST_SectionBox).ToElements();
				ElementSet elementSet = new ElementSet();
				foreach (Element element in enumerable)
				{
					if (element.CanBeHidden(view3d))
					{
						elementSet.Insert(element);
					}
				}
				if (elementSet.Size > 0)
				{
					RevitVersionFuncs.HideElementSetInthe3dView(elementSet, view3d);
				}
			}
			List<Element> list = new List<Element>();
			List<Element> list2 = new List<Element>();
			this.Get3DGridElements(ref list, ref list2);
			if (!partial3DViewForm.Show3DGird)
			{
				ElementSet elementSet2 = new ElementSet();
				foreach (Element element2 in list)
				{
					elementSet2.Insert(element2);
				}
				foreach (Element element3 in list2)
				{
					elementSet2.Insert(element3);
				}
				if (elementSet2.Size > 0)
				{
					RevitVersionFuncs.HideElementSetInthe3dView(elementSet2, view3d);
					return;
				}
			}
			else
			{
				foreach (Element element4 in list2)
				{
					this.CopyGridText(element4 as TextNote, view3d, boundingBoxXYZ);
				}
			}
		}

		private bool LessThan(double val1, double val2)
		{
			return val1 - val2 < -1E-09;
		}

		private bool GreaterThan(double val1, double val2)
		{
			return val1 - val2 > 1E-09;
		}

		private bool Lessthan_Or_Equal(double val1, double val2)
		{
			return val1 - val2 <= 1E-09;
		}

		private void GetTopLevel(ref Level topLevel)
		{
			double elevation = this.m_Revit.Application.ActiveUIDocument.ActiveView.GenLevel.Elevation;
			double num = double.MaxValue;
			foreach (Element element in new FilteredElementCollector(this.m_Doc).OfClass(typeof(Level)).ToElements())
			{
				Level level = element as Level;
				double num2 = level.Elevation - elevation;
				if (num2 >= 0.0001 && num2 < num)
				{
					num = num2;
					topLevel = level;
				}
			}
		}

		private Workset GetActiveWorkset(Autodesk.Revit.DB.Document doc)
		{
			WorksetTable worksetTable = doc.GetWorksetTable();
			WorksetId activeWorksetId = worksetTable.GetActiveWorksetId();
			return worksetTable.GetWorkset(activeWorksetId);
		}

		private string ReplaceInvalidFileNameChars(string fillName)
		{
			string text = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
			string text2 = fillName;
			string text3 = text;
			for (int i = 0; i < text3.Length; i++)
			{
				text2 = text2.Replace(text3[i].ToString(), "");
			}
			return text2;
		}

		private void get3dViewName(Autodesk.Revit.DB.Document doc, View3D view3d, bool useDefault3dViewName)
		{
			string text = "局部三维视图";
			Workset activeWorkset = this.GetActiveWorkset(doc);
			if (activeWorkset != null && activeWorkset.Name.CompareTo("") != 0)
			{
				text = text + "_" + this.ReplaceInvalidFileNameChars(activeWorkset.Name);
			}
			if (useDefault3dViewName)
			{
				FilteredElementIterator elementIterator = new FilteredElementCollector(doc).OfClass(typeof(Autodesk.Revit.DB.View)).GetElementIterator();
				elementIterator.Reset();
				while (elementIterator.MoveNext())
				{
					Element element = elementIterator.Current;
					Autodesk.Revit.DB.View view = element as Autodesk.Revit.DB.View;
					if (view != null && !view.IsTemplate && (int)view.ViewType == 4 && view.Name.CompareTo(text) == 0)
					{
						this.m_Doc.Delete(view.Id);
						break;
					}
				}
				view3d.Name = text;
				return;
			}
			List<int> list = new List<int>();
			FilteredElementIterator elementIterator2 = new FilteredElementCollector(doc).OfClass(typeof(Autodesk.Revit.DB.View)).GetElementIterator();
			elementIterator2.Reset();
			while (elementIterator2.MoveNext())
			{
				Element element2 = elementIterator2.Current;
				Autodesk.Revit.DB.View view2 = element2 as Autodesk.Revit.DB.View;
				if (view2 != null && !view2.IsTemplate && (int)view2.ViewType == 4)
				{
					string name = view2.Name;
					string text2 = text;
					if (text.CompareTo(name) != 0)
					{
						int num = name.LastIndexOf(text2);
						if (num > -1)
						{
							string value = name.Substring(num + text2.Length + 1);
							try
							{
								int item = Convert.ToInt32(value);
								list.Add(item);
							}
							catch (Exception)
							{
							}
						}
					}
				}
			}
			list.Sort();
			int num2 = 0;
			if (list.Count > 0)
			{
				num2 = list[list.Count - 1];
			}
			view3d.Name = text + "_" + (num2 + 1).ToString();
		}

		private void Get3DGridElements(ref List<Element> girdCurveList, ref List<Element> gridTextList)
		{
			new FilteredElementCollector(this.m_Doc);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc).OfCategory(BuiltInCategory.OST_Lines).OfClass(typeof(CurveElement));
			FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(this.m_Doc).OfCategory(BuiltInCategory.OST_TextNotes).OfClass(typeof(TextNote));
			foreach (ElementId elementId in filteredElementCollector.ToElementIds())
			{
				Element element = this.m_Doc.GetElement(elementId);
				if ((!(element.GetType() != typeof(ModelArc)) || !(element.GetType() != typeof(ModelLine))) && this.ReadData(element) == "Grid")
				{
					girdCurveList.Add(element);
				}
			}
			foreach (ElementId elementId2 in filteredElementCollector2.ToElementIds())
			{
				Element element2 = this.m_Doc.GetElement(elementId2);
				if (this.ReadData(element2) == "Grid")
				{
					gridTextList.Add(element2);
				}
			}
		}

		private string ReadData(Element elem)
		{
			string result;
			try
			{
				Entity entity = elem.GetEntity(Schema.Lookup(CreatePartial3dView.DataGuid));
				if (entity == null)
				{
					result = "";
				}
				else
				{
					result = entity.Get<string>(Schema.Lookup(CreatePartial3dView.DataGuid).GetField("HYData"));
				}
			}
			catch
			{
				result = "";
			}
			return result;
		}

		private void CopyGridText(TextNote textNote, View3D view3d, BoundingBoxXYZ boundingBox)
		{
			XYZ textNoteCoord = RevitElementExtension.GetTextNoteCoord(textNote);
			if (this.LessThan(textNoteCoord.X, boundingBox.Min.X) || this.GreaterThan(textNoteCoord.X, boundingBox.Max.X) || this.LessThan(textNoteCoord.Y, boundingBox.Min.Y) || this.GreaterThan(textNoteCoord.Y, boundingBox.Max.Y) || this.LessThan(textNoteCoord.Z, boundingBox.Min.Z) || this.GreaterThan(textNoteCoord.Z, boundingBox.Max.Z))
			{
				return;
			}
			TextNote textNode = this.m_Doc.GetTextNode(view3d, textNoteCoord, XYZ.BasisX, XYZ.BasisY, 1.0, (Autodesk.Revit.DB.TextAlignFlags)128, textNote.Text);
			textNode.ChangeTypeId(textNote.Symbol.Id);
			RevitElementExtension.SetTextNoteWidth(textNode, 1.0);
		}

		private ExternalCommandData m_Revit;

		private Document m_Doc;

		private static Guid DataGuid = new Guid("356cda5a-e6c5-4c2f-a9ef-b1223336b8c8");
	}
}
